var ExcelHelp = function(_opt){
    this.init();
}
ExcelHelp.prototype = {
    //回调方法
    doCallback: function (fn, args) {
        return fn.apply(this, args);
    },
    //事件集合
    eve:{
        //打开前事件
        beforSelect:"beforselect",
        //选择文件事件
        select:"select",
        //开始读取
        beforRead:"beforRead",
        //读取完成
        read:"read",
        //开始导出Excel
        beforOut:"beforOut",
        typeErr:"typeErr",
        clearFile:"clearFile"
    },
    //初始化
    init:function(){
        var t = this;
        var input = document.createElement("input");
        input.type="file";
        input.style="display:none;";
        document.body.appendChild(input);
        t.fileEl = $(input);

        t.fileEl.on("change",function(e){
            var files = e.target.files;
            var fileReader = new FileReader();
            fileReader.onload = function(ev) {
                try {
                    var data = ev.target.result,
                        workbook = XLSX.read(data, {
                            type: 'binary'
                        }), // 以二进制流方式读取得到整份excel表格对象
                        persons = []; // 存储获取到的数据
                    t.trigger(t.eve.select,[files[0]]);
                } catch (e) {
                    if(t.log){
                        console.log(t.message.typeerr);
                    }
                    t.trigger(t.eve.typeErr,[]);
                    t.clearFile();
                    return;
                }
            }
            if(files && files[0]){
                var file_type=files[0].name.substring(files[0].name.lastIndexOf(".")+1);    
                if(t.fileType.indexOf(file_type)<0){
                    if(t.log){
                        console.log(t.message.typeerr);}
                    t.trigger(t.eve.typeErr,[files[0]]);
                    return;
                }else{
                    // 以二进制方式打开文件
                    fileReader.readAsBinaryString(files[0]);
                    t.file = files[0];
                }
            }
        })
    },
    //触发事件
    trigger:function(ename,args){
        var t = this;
        if(t.log){
            console.log("触发事件"+ename);
        }
        //参数
        var r = $.makeArray(args);
        //触发属性on事件
        if(t['on'+ename]){t.doCallback(t['on'+ename],r);}
        //触发由on注册的事件
        if(!t._eves){t._eves={};}
        if(t._eves[ename] && t._eves[ename].length>0){
            $.each(t._eves[ename], function(n, fn) {
                t.doCallback(fn,r);
            });
        }
        if(ename!='alleve'){
            t.trigger('alleve',[ename,args])
        }
    },
    //注册事件
    on:function(ename,fun){
        var t = this;
        var enames = ename.split(" ");
        if(!t._eves){t._eves={};}
        $.each(enames, function(n, name) {
            if (name) {
                if(!t._eves[name]){t._eves[name]=[];}
                t._eves[name].push(fun);
            }
        });
        return t;
    },
    //上传控件
    fileEl:{},
    //文件类型 验证用
    fileType: ["xls","xlsx"],
    //是否开启日志
    log:true,
    //提示的文本
    message:{typeerr:"文件类型不正确。请重新选择文件"},
    //当前选择的文件
    file:{},
    //数据项
    excelData:[],
    //页签名称集合
    sheets:[],
    //清除文件
    clearFile:function(){
        var t = this;
        t.file = null;
        t.trigger(t.eve.clearFile,[]);
    },
    //打开Excel文件
    select:function(){
        var t = this;
        //触发点击前事件
        t.trigger(t.eve.beforSelect,[]);
        //点击事件是在init中注册的
        t.fileEl.click();
    },
    //读取Excel文件
    read:function(_fun){
        var t = this;
        var fileReader = new FileReader();
        fileReader.onload = function(ev) {
            try {
                var data = ev.target.result,
                    workbook = XLSX.read(data, {
                        type: 'binary'
                    }), // 以二进制流方式读取得到整份excel表格对象
                    persons = []; // 存储获取到的数据
                    sheets = [];//存储获取到的Sheet名称
            } catch (e) {
                if(t.log){
                    console.log(t.message.typeerr);
                }
                t.trigger(t.eve.typeErr,[]);
                t.clearFile();
                return;
            }
            
             // 表格的表格范围，可用于判断表头是否数量是否正确
             var fromTo = '';
             // 遍历每张表读取
             for (var sheet in workbook.Sheets) {
                 if (workbook.Sheets.hasOwnProperty(sheet)) {
                     fromTo = workbook.Sheets[sheet]['!ref'];
                     if(t.log){console.log(fromTo);}
                     sheets.push(sheet);
                     persons.push(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
                     // break; // 如果只取第一张表，就取消注释这行
                 }
             }
    
             if(t.log){console.log(persons);}
             t.sheets = sheets;
             t.excelData = persons;
             t.trigger(t.eve.read,[t.excelData,t.sheets]);
             if(_fun && $.isFunction(_fun)){
                 t.doCallback(_fun,[t.excelData,t.sheets]);
             }
        }
        if(t.file){
            t.trigger(t.eve.beforRead,[]);
            // 以二进制方式打开文件
            fileReader.readAsBinaryString(t.file);
        }else{
            t.trigger(t.eve.typeErr,[]);
        }
    },
    //导出Excel
    out:function(FileName, JSONData, ShowLabel) {  
        //先转化json  
        var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;  
        
        if((!ShowLabel || ShowLabel.length==0) && arrData.length!=0){
            ShowLabel=[];
            for(var n in arrData[0]){
                var d = {};
                d[n] = n;
                ShowLabel.push(d);
            }
        }
        var excel = '<table>';      
          
        //设置表头  
        var row = "<tr align='left'>";//设置Excel的左居中
        for (var i = 0, l = ShowLabel.length; i < l; i++) {  
            for (var key in ShowLabel[i]) {
                row += "<td>" + ShowLabel[i][key] + '</td>';  
            }
        }  
          
          
        //换行  
        excel += row + "</tr>";  
          
        //设置数据  
        for (var i = 0; i < arrData.length; i++) {  
            var rowData = "<tr align='left'>"; 
    
            for (var y = 0; y < ShowLabel.length; y++) {
                for(var k in ShowLabel[y]){
                    if (ShowLabel[y].hasOwnProperty(k)) {
                         rowData += "<td style='vnd.ms-excel.numberformat:@'>" + (arrData[i][k]===null? "" : arrData[i][k]) + "</td>";
    　　　　　　　　　　　　　　　　　 //vnd.ms-excel.numberformat:@ 输出为文本
                    }
                }
            }
    
            excel += rowData + "</tr>";  
        }  
    
        excel += "</table>";  
    
        var excelFile = "<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>";  
        excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel; charset=UTF-8">';  
        excelFile += '<meta http-equiv="content-type" content="application/vnd.ms-excel';  
        excelFile += '; charset=UTF-8">';  
        excelFile += "<head>";  
        excelFile += "<!--[if gte mso 9]>";  
        excelFile += "<xml>";  
        excelFile += "<x:ExcelWorkbook>";  
        excelFile += "<x:ExcelWorksheets>";  
        excelFile += "<x:ExcelWorksheet>";  
        excelFile += "<x:Name>";  
        excelFile += "没想好QQ:935732994";  
        excelFile += "</x:Name>";  
        excelFile += "<x:WorksheetOptions>";  
        excelFile += "<x:DisplayGridlines/>";  
        excelFile += "</x:WorksheetOptions>";  
        excelFile += "</x:ExcelWorksheet>";  
    
    
        excelFile += "</x:ExcelWorksheets>";  
        excelFile += "</x:ExcelWorkbook>";  
        excelFile += "</xml>";  
        excelFile += "<![endif]-->";  
        excelFile += "</head>";  
        excelFile += "<body>";  
        excelFile += excel;     
        excelFile += "</body>";  
        excelFile += "</html>";  
    
          
        var uri = 'data:application/vnd.ms-excel;charset=utf-8,' + encodeURIComponent(excelFile);  
          
        var link = document.createElement("a");   
        var iframe = document.createElement("iframe");    
        iframe.id = "_iframe";
        iframe.style = "height:0px;width:0px;border:none;"
        document.body.appendChild(iframe);  
        setTimeout(function(){
    
            var _iframe = document.getElementById("_iframe");
            var iwindow = _iframe.contentWindow;
            var idoc = iwindow.document;
            link.href = uri;  
            link.id = '_link';
            link.style = "visibility:hidden";  
            link.download = FileName + ".xls";  
            idoc.body.appendChild(link);  
            var _link = idoc.getElementById("_link");
            _link.click();  
            setTimeout(function(){
                document.body.removeChild(iframe);   
            },220)
            //idoc.body.removeChild(link);  
        },120)
    }  
}
//表帮助类
var DataTable = function(){
    this.init();
}
//行类
var _row = function(DataTable){
    this.DataTable = DataTable;
};
//行类 没啥用就为方法 改！个！名！
//注意 操作对象为父级DataTable 不能单独存在
_row.prototype = {
    //新增
    add:function(_r){
        var t = this;
        if(Array.isArray(_r)){
            _r.forEach(function(v){
                t.DataTable.rows.push(v);
            })
        }else{
            t.DataTable.rows.push(_r);
        }
    },
    //查询
    select:function(_fun){
        var t = this;
        return Array.prototype.find.apply(t.DataTable.rows, arguments);
    },
    //查找全部
    selectAll:function(_fun){
        var t = this;
        return Array.prototype.filter.apply(t.DataTable.rows, arguments);
    },
    //行数
    count:function(){
        var t = this;
        return t.DataTable.rows.length;
    }
}
//列类
var _column = function(DataTable){
    this.DataTable = DataTable;
}
_column.prototype = {
    //新增列
    add:function(_col){
        var t = this;
        if(Array.isArray(_col)){
            _col.forEach(function(v){
                t.DataTable.columns.push(v);
            })
        }else if(typeof _col === "string"){
            t.DataTable.columns.push(_col);
        }
    }
}
DataTable.prototype = {
    init:function(){
        var t = this;
        //列子类
        t.column = new _column(t);
        //行子类
        t.row = new _row(t);
        //列集合
        t.columns = [];
        //行集合
        t.rows = [];
    },
    newRow:function(){
        var t=this;
        var _r = {};
        t.columns.forEach(function(item){
            _r[item] = '';
        });
        return _r;
    },
    toJson:function(){
        var t = this;
        return t.rows;
    }
};